﻿/*********************************************
File name:  DrugAppendController
Author:     李潘云
Date:       2019-04-30
Description:  IDataReader转换为对象实体
Function List：
******************************************
********************************************/
using RM.BasicLibrary.Exceptions;
using RM.BasicLibrary.Resources;
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;

namespace RM.BasicLibrary.Models
{
    public interface IDataConvert
    {
        T ToEntity<T>(DataRow dr) where T : new();
        List<T> ToEntitys<T>(DataTable dt) where T : new();
        T ToEntity<T>(IDataReader dr) where T : new();
        IEnumerable<T> ToEntitys<T>(IDataReader dr) where T : new();
    }
    /// <summary>
    /// 
    /// </summary>
    public class DataConvert : IDataConvert
    {
        /// <summary>
        /// 把DataRow对象转成实体类。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public T ToEntity<T>(DataRow dr) where T : new()
        {
            if (dr == null)
                return default(T);
            T t = new T();
            PropertyInfo[] propertys = t.GetType().GetProperties();
            DataColumnCollection Columns = dr.Table.Columns;
            foreach (PropertyInfo property in propertys)
            {
                if (!property.CanWrite) continue;
                string columnName = property.Name;
                if (Columns.Contains(columnName))
                {
                    object value = dr[columnName];
                    if (value is DBNull) continue;
                    Root.Ins.ExFilter.Execute(() => property.SetValue(t, value, null));
                }
            }
            return t;
        }

        /// <summary>
        /// 把DataTable对象转成实体类的列表。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public List<T> ToEntitys<T>(DataTable dt) where T : new()
        {
            List<T> list = new List<T>();
            Root.Ins.ExFilter.Execute(() =>
            {
                if (dt != null && dt.Rows.Count > 0)
                    foreach (DataRow dr in dt.Rows) list.Add(ToEntity<T>(dr));
            });
             return list;
        }

        /// <summary>
        /// 把IDataReader对象转成实体类。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr">需要参数的方法dr.Read()返回值为true。</param>
        /// <returns></returns>
        private T DataReaderToEntity<T>(IDataReader dr) where T : new()
        {
            T t = new T();
            PropertyInfo[] propertys = t.GetType().GetProperties();
            List<string> fieldNameList = new List<string>();
            for (int i = 0; i < dr.FieldCount; i++) fieldNameList.Add(dr.GetName(i).ToUpper());
            foreach (PropertyInfo property in propertys)
            {
                if (!property.CanWrite) continue;
                string fieldName = property.Name;
                if (fieldNameList.Contains(fieldName.ToUpper()))
                {
                    object value = dr[fieldName];
                    if (value is DBNull) continue;
                    Root.Ins.ExFilter.Execute(() => property.SetValue(t, value, null), Root.BasicIns.GetValue(ModelsResource.PropertyAssignmentException));
                }
            }
             return t;
        }

        /// <summary>
        /// 把IDataReader对象转成实体类。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public T ToEntity<T>(IDataReader dr) where T : new()
        {
            if (dr != null && dr.Read()) return DataReaderToEntity<T>(dr);
            return default(T);
        }

        /// <summary>
        /// 把IDataReader对象转成实体类的列表。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public IEnumerable<T> ToEntitys<T>(IDataReader dr) where T : new()
        {
            List<T> list = new List<T>();
            if (dr != null)
                while (dr.Read())
                    list.Add(DataReaderToEntity<T>(dr));
            return list;
        }
    }
}
